package com.pan.insist.engine;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.pan.insist.bean.PathConstant;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;


/**
 * @author kaiji
 */
public class InsistTemplateEngine extends AbstractTemplateEngine {

	private Configuration configuration;

	public InsistTemplateEngine() {
	}

	@Override
	public InsistTemplateEngine init(ConfigBuilder configBuilder) {
		super.init(configBuilder);
		this.configuration = new Configuration(Configuration.VERSION_2_3_28);
		this.configuration.setDefaultEncoding(ConstVal.UTF8);
		this.configuration.setClassForTemplateLoading(InsistTemplateEngine.class, "/");
		return this;
	}

	@Override
	public void writer(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
		Template template = this.configuration.getTemplate(templatePath);
		FileOutputStream fileOutputStream = new FileOutputStream(new File(outputFile));
		template.process(objectMap, new OutputStreamWriter(fileOutputStream, ConstVal.UTF8));
		fileOutputStream.close();
		logger.debug("模板:" + templatePath + ";  文件:" + outputFile);
	}

	@Override
	public String templateFilePath(String filePath) {
		return filePath + ".ftl";
	}


	/**
	 * 处理输出目录
	 */
	@Override
	public InsistTemplateEngine mkdirs() {
		getConfigBuilder().getPathInfo().forEach((key, value) -> {
			File dir = new File(value);
			if (!dir.exists()) {
				boolean result = dir.mkdirs();
				if (result) {
					logger.debug("创建目录： [" + value + "]");
				}
			}
		});
		return this;
	}

	InsistTemplateEngine batchOutputs() {
		try {
			List<TableInfo> tableInfoList = getConfigBuilder().getTableInfoList();
			for (TableInfo tableInfo : tableInfoList) {
				Map<String, Object> objectMap = getObjectMap(tableInfo);
				Map<String, String> pathInfo = getConfigBuilder().getPathInfo();
				TemplateConfig template = getConfigBuilder().getTemplate();
				// 自定义内容
				InjectionConfig injectionConfig = getConfigBuilder().getInjectionConfig();
				if (null != injectionConfig) {
					injectionConfig.initMap();
					objectMap.put("cfg", injectionConfig.getMap());
					List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
					if (CollectionUtils.isNotEmpty(focList)) {
						for (FileOutConfig foc : focList) {
							if (isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
								writer(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
							}
						}
					}
				}
				// Mp.java
				String entityName = tableInfo.getEntityName();
				if (null != entityName && null != pathInfo.get(ConstVal.ENTITY_PATH)) {
					String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName);
					if (isCreate(FileType.ENTITY, entityFile)) {
						writer(objectMap, templateFilePath(template.getEntity(getConfigBuilder().getGlobalConfig().isKotlin())), entityFile);
					}
				}
				// MpMapper.java
				if (null != tableInfo.getMapperName() && null != pathInfo.get(ConstVal.MAPPER_PATH)) {
					String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + suffixJavaOrKt()), entityName);
					if (isCreate(FileType.MAPPER, mapperFile)) {
						writer(objectMap, templateFilePath(template.getMapper()), mapperFile);
					}
				}
				// MpMapper.xml
				if (null != tableInfo.getXmlName() && null != pathInfo.get(ConstVal.XML_PATH)) {
					String xmlFile = String.format((pathInfo.get(ConstVal.XML_PATH) + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
					if (isCreate(FileType.XML, xmlFile)) {
						writer(objectMap, templateFilePath(template.getXml()), xmlFile);
					}
				}
				// IMpService.java
				if (null != tableInfo.getServiceName() && null != pathInfo.get(ConstVal.SERVICE_PATH)) {
					String serviceFile = String.format((pathInfo.get(ConstVal.SERVICE_PATH) + File.separator + tableInfo.getServiceName() + suffixJavaOrKt()), entityName);
					if (isCreate(FileType.SERVICE, serviceFile)) {
						writer(objectMap, templateFilePath(template.getService()), serviceFile);
					}
				}
				// MpServiceImpl.java
				if (null != tableInfo.getServiceImplName() && null != pathInfo.get(ConstVal.SERVICE_IMPL_PATH)) {
					String implFile = String.format((pathInfo.get(ConstVal.SERVICE_IMPL_PATH) + File.separator + tableInfo.getServiceImplName() + suffixJavaOrKt()), entityName);
					if (isCreate(FileType.SERVICE_IMPL, implFile)) {
						writer(objectMap, templateFilePath(template.getServiceImpl()), implFile);
					}
				}
				// MpController.java
				if (null != tableInfo.getControllerName() && null != pathInfo.get(ConstVal.CONTROLLER_PATH)) {
					String controllerFile = String.format((pathInfo.get(ConstVal.CONTROLLER_PATH) + File.separator + tableInfo.getControllerName() + suffixJavaOrKt()), entityName);
					if (isCreate(FileType.CONTROLLER, controllerFile)) {
						writer(objectMap, templateFilePath(template.getController()), controllerFile);
					}
				}

				assert entityName != null;
				entityName = StringUtils.uncapitalize(entityName.substring(0, entityName.indexOf("Model")));
				// 主页面
				if (null != pathInfo.get(PathConstant.PAGE_PATH)) {
					String indexPageFile = String.format(pathInfo.get(PathConstant.PAGE_PATH) + File.separator + "%s" + File.separator + "list.ftl", entityName);
					if (isCreate(FileType.OTHER, indexPageFile)) {
						writer(objectMap, templateFilePath("/templates/page.ftl"), indexPageFile);
					}
				}

				// 主页面的JS
				if (null != pathInfo.get(PathConstant.PAGES)) {
					String indexJsPageFile = String.format(pathInfo.get(PathConstant.PAGES) + File.separator + "%s" + File.separator + entityName + ".js", entityName);
					if (isCreate(FileType.OTHER, indexJsPageFile)) {
						writer(objectMap, templateFilePath("/templates/page.js"), indexJsPageFile);
					}
				}

				if (null != pathInfo.get(PathConstant.PAGE_INPUT)) {
					String addPageFile = String.format(pathInfo.get(PathConstant.PAGE_INPUT) + File.separator + "%s" + File.separator + "input.ftl", entityName);
					if (isCreate(FileType.OTHER, addPageFile)) {
						writer(objectMap, templateFilePath("/templates/add_page.ftl"), addPageFile);
					}
				}

				if (null != pathInfo.get(PathConstant.PAGE_VIEW)) {
					String viewPageFile = String.format(pathInfo.get(PathConstant.PAGE_VIEW) + File.separator + "%s" + File.separator + "view.ftl", entityName);
					if (isCreate(FileType.OTHER, viewPageFile)) {
						writer(objectMap, templateFilePath("/templates/view_page.ftl"), viewPageFile);
					}
				}

			}
		} catch (Exception e) {
			logger.error("无法创建文件，请检查配置信息！", e);
		}
		return this;
	}
}
